package com.itheima.tlias.aop;

import com.itheima.tlias.comment.MyComment;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

//@Component
//@Aspect //当前类为切面类
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)//指定执行顺序，值越小，执行顺序越靠前
public class TestAspect {

    @Pointcut("execution(* com.itheima.tlias.service.impl.*.*(..))")
    public void pc() {
    }


    //环绕通知
    @Around("pc()")
        public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {
        Signature signature = pjp.getSignature();
        //获取方法名
        String methodName = signature.getName();
        //获取类名
        String className = signature.getDeclaringTypeName();
        //获取所有参数
        Object[] args = pjp.getArgs();
        //获取返回值
        Object proceed = pjp.proceed();
        //记录方法执行开始时间
        long begin = System.currentTimeMillis();

        //执行原始方法
        Object result = pjp.proceed();

        //记录方法执行结束时间
        long end = System.currentTimeMillis();

        //计算方法执行耗时
        log.info("方法执行耗时: {}毫秒", end - begin);
        return result;
    }

    @AfterThrowing("@annotation(com.itheima.tlias.comment.MyComment)")
    public void afterThrowing(JoinPoint jp) throws Throwable {
        Signature signature = jp.getSignature();
        String methodName = signature.getName();
        String className = signature.getDeclaringTypeName();
        log.info("AfterThrowing");
    }
    //后置通知

    @AfterReturning("@annotation(mc)")
    public void afterReturning(MyComment mc) throws Throwable {
        log.info("AfterReturning");
    }


    @After("pc()||execution(* com.itheima.tlias.service.impl.*.*(..))")
    public void after() throws Throwable {
        log.info("After");
    }

    @Before("execution(* com.itheima.tlias.service.impl.*.*(..))")
    public void before() throws Throwable {
        log.info("Before");
    }

    @Before("pc()")
    public void afterBefore() {
        log.info(" Before -> after ...");
    }
}